
import sys
from PyQt5.QtWidgets import *
from PyQt5 import  uic
from PyQt5.QtCore import *
from PyQt5.QtGui import *

from collections import deque
import time
import threading
import  os
import pyttsx3
import pygame

import traceback
from  TimerWindowsShow import TimerWindowShow
# from functiontest import TestWidget
from ShowPPT import ShowPPT
from EditMissonView import CustomDialog

from Register import Register

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        loader = uic
        self.total_seconds=0
        self.ShowData=''

        self.ui = loader.loadUi(r'../ui/MainWindows2.0v.ui')
        self.setCentralWidget(self.ui)
        self.setFixedSize(self.ui.size())

        self.InitSpinButtons()
        self.InitPushButton()


        self.lcdNumber = self.ui.findChild(QLCDNumber, 'LcdShow')
        # print(self.lcdNumber)
        self.TabWidget = self.ui.findChild(QTabWidget, 'tabWidget')
        self.InputData=self.ui.findChild(QLineEdit,'InputData')
        self.InputData.setPlaceholderText("默认NULL，即当前窗口的计时器名称")
        self.RemindMissonsList=self.ui.findChild(QTableView,'RemindMissonsList')

        self.DigitalColor=self.ui.findChild(QComboBox,'DigitalColor')
        # 创建一个处理方法来响应用户的选择


        self.initDigitalColor()
        self.initmodelData()
        self.InitShack()

        # 在应用程序启动时显示初始值
        self.lcdShowDisplay(0)

        self.getdatalists=None
        self.timeList=None

        self.sub_windows = []  # 存储子窗口实例的列表
        self.sub_windows2=[]

    def InitShack(self):
        self.shake_timer = QTimer(self)
        self.shake_timer.timeout.connect(self.shake)
        self.shake_count = 0
        self.shake_duration = 10  # 持续时间，单位为毫秒

    def initDigitalColor(self):
        self.DigitalColor.activated.connect(self.handle_color_selection)
        # 添加颜色选项
        colors = ["Red", "Green", "Blue", "Yellow","Black","White"]
        self.DigitalColor.addItems(colors)

    def initmodelData(self):
        self.model = QStandardItemModel()
        self.RemindMissonsList.setModel(self.model)

        # 设置表头
        self.model.setHorizontalHeaderLabels(["序号", "名称", "时间", "行为", "绑定目标"])
        # 设置单元格不可编辑
        self.RemindMissonsList.setEditTriggers(QTableView.NoEditTriggers)
        # 启用右键菜单
        self.RemindMissonsList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.RemindMissonsList.customContextMenuRequested.connect(self.show_context_menu)
        # 连接双击事件到删除记录的功能
        self.RemindMissonsList.doubleClicked.connect(self.delete_record)




    def show_context_menu(self, pos):
        # 创建右键菜单
        # print("Show context")
        menu = QMenu(self)

        # 添加删除记录的动作
        delete_action = QAction("删除记录", self)
        delete_action.triggered.connect(self.delete_record)
        menu.addAction(delete_action)

        # 显示菜单在鼠标右键位置
        menu.exec_(self.RemindMissonsList.mapToGlobal(pos))

    def delete_record(self):
        # 删除选中的记录
        selected_rows = self.RemindMissonsList.selectionModel().selectedRows()
        for row in reversed(selected_rows):
            self.model.removeRow(row.row())

    def browse_file(self):
        options = QFileDialog.Options()
        options |= QFileDialog.ReadOnly

        # 打开文件对话框
        file_path, _ = QFileDialog.getOpenFileName(self, "Select File", "", "*.ppt;;*.pptx", options=options)

        if file_path:
            self.FilePathEdit.setText(file_path)


    def InitPushButton(self):
        self.CreateMission = self.ui.findChild(QPushButton, 'CreateMission')
        self.StarOrStopTimer=self.ui.findChild(QPushButton, 'StartTimer')
        self.ChooseFileButton=self.ui.findChild(QPushButton, 'ChooseFileButton')
        self.OtherMode=self.ui.findChild(QPushButton, 'OtherMode')
        self.AddRMB=self.ui.findChild(QPushButton,'AddRMB')
        # print(self.AddRMB)
        # print(self.CreateMissoin)
        self.CreateMission.clicked.connect(self.addMission)
        self.StarOrStopTimer.clicked.connect(self.toggle_button_click)
        self.toggle_state = True
        self.TimerReady = False
        self.ChooseFileButton.clicked.connect(self.browse_file)
        self.OtherMode.clicked.connect(self.StartOtherMode)
        self.AddRMB.clicked.connect(self.DialogtoEditListView)

    def InitSpinButtons(self):
        self.TimerHours=self.ui.findChild(QSpinBox, 'TimerHours')
        self.TimerMinutes=self.ui.findChild(QSpinBox, 'TimerMinutes')
        self.TimerSeconds=self.ui.findChild(QSpinBox, 'TimerSeconds')

        self.FilePathEdit=self.ui.findChild(QLineEdit,'FilePath')

        # 连接SpinBox的valueChanged信号到updateDisplay方法
        self.TimerHours.valueChanged.connect(self.updateDisplay)
        self.TimerMinutes.valueChanged.connect(self.updateDisplay)
        self.TimerSeconds.valueChanged.connect(self.updateDisplay)

    def DialogtoEditListView(self):
        # print('asdasdasd')
        self.Dialogwin = CustomDialog()
        self.Dialogwin.data_signal.connect(self.get_sig_togetData)
        self.sub_windows2.append(self.Dialogwin)
        self.Dialogwin.show()


    def get_sig_togetData(self,sig):
        print(sig)
        self.RemindData=self.Dialogwin.get_table_data()
        print(self.RemindData)
        self.WriteDataToRemindMissonsList(self.RemindData)


    def WriteDataToRemindMissonsList(self,data):
        data=self.ReEditData(data)
        # print(data)
        self.add_Record(data)
        self.getdatalists=self.AppendRemindDataList()

        if self.getdatalists is not None:
            self.dataNoneFlag=True
            self.getdatalistsHand(self.getdatalists)
        else:
            self.dataNoneFlag=False
        print(self.getdatalists)

    def AppendRemindDataList(self):
        row_count =self.model.rowCount()
        column_count = self.model.columnCount()
        # 遍历列，获取每列的数据
        onerowdata=[]
        for row in range(row_count):
            allcolumdata = []
            for column in range(column_count):
                index = self.model.index(row, column)
                # 使用 data() 方法获取单元格的数据
                cell_data = self.model.data(index, Qt.DisplayRole)
                if cell_data=='':
                    cell_data ='NULL'
                # print(cell_data)
                allcolumdata.append(cell_data)
            onerowdata.append(allcolumdata)
        return onerowdata

    def add_Record(self, data):
        if len(data) != 5:
            # 确保数据列表包含五个元素，如果不包含，则不执行添加操作
            return
        # 获取当前行数，即模型中的行数
        row = self.model.rowCount()
        # 为每个数据项创建一个QStandardItem并添加到模型中
        for col, item in enumerate(data):
            self.model.setItem(row, col, QStandardItem(item))
        # 增加序号
        self.model.setItem(row, 0, QStandardItem(str(row + 1)))
        # # 增加一行
        # self.model.insertRow(row)

    def ReEditData(self,data):
        listdata=[None,]
        for row_data in data.values():
            for key,value in row_data.items():
                if key.startswith('Column2'):
                    listdata.append(value)
        return listdata


    def updateDisplay(self):
        hours = self.TimerHours.value()
        minutes = self.TimerMinutes.value()
        seconds = self.TimerSeconds.value()

        self.total_seconds = hours * 3600 + minutes * 60 + seconds

        self.lcdShowDisplay(self.total_seconds)

    def lcdShowDisplay(self, total_seconds):
        # 计算时、分和秒
        hours = total_seconds // 3600
        total_seconds %= 3600
        minutes = total_seconds // 60
        seconds = total_seconds % 60

        # 格式化并显示在lcdNumber中
        timeShow = f'{hours:02d}:{minutes:02d}:{seconds:02d}'
        self.lcdNumber.display(timeShow)

    def StartOtherMode(self):
        total_seconds = self.total_seconds
        ShowData = self.InputData.text()
        FilePath=self.FilePathEdit.text()
        getdatalists=self.getdatalists
        TheTimerId=self.InputData.text()
        lcdsetStyleSheet = self.lcdNumber.styleSheet()
        print('实例化Mode')
        showPPT=ShowPPT(path=FilePath,total_seconds=total_seconds,ShowData=ShowData,getdatalists=getdatalists,TheTimerId=TheTimerId,lcdsetStyleSheet=lcdsetStyleSheet)
        showPPT.show.sub_window.subsubsub_window_signal.connect(self.ReShowMainWindow)

        self.hide()
        self.ui.hide()

    def ReShowMainWindow(self):
        print('ReShowMainWindow')
        self.show()
        self.ui.show()

    def addMission(self,mode=None):
        # print('ttttss')
        total_seconds = self.total_seconds
        lcdsetStyleSheet=self.lcdNumber.styleSheet()
        ShowData = self.InputData.text()
        getdatalists = self.getdatalists
        TheTimerId=self.InputData.text()

        mode=mode
        sub_window = TimerWindowShow(total_seconds=total_seconds, ShowData=ShowData,mode=mode,getdatalists=getdatalists,TheTimerId=TheTimerId,lcdsetStyleSheet=lcdsetStyleSheet)

        sub_window.showSignal.connect(self.showSubWindow)

        self.sub_windows.append(sub_window)

    def showSubWindow(self, sub_window):
        sub_window.ui.show()

    def toggle_button_click(self):
        # print('sdasdsa')
        if self.TimerReady:
            if self.toggle_state:
                self.TimerStop()
                self.toggle_state = False
            else:
                self.TimerWork()
                self.toggle_state = True
        else:
            # print('sdasdaccccc')
            self.TimerWork_ready()
            self.TimerReady = True

    def TimerWork_ready(self):

        # 创建一个 QTimer 对象
        self.timer = QTimer(self)
        self.currentSeconds=self.total_seconds
        self.timer.timeout.connect(self.updateTimer)
        self.TimerWork()

    def TimerWork(self):
        if not self.timer.isActive():
            print('startTimer')
            self.timer.start(1000)

    def TimerStop(self):
        if self.timer.isActive():
            print('stopTimer')
            self.timer.stop()

    def updateTimer(self):
        if self.currentSeconds > 0:
            self.currentSeconds -= 1
            if self.timeList is not None:
                self.CheckTime(self.currentSeconds)
            self.lcdShowDisplay(self.currentSeconds)
        else:
            self.TimerStop()

    def handle_color_selection(self, index):
        selected_color = self.DigitalColor.currentText()
        style_sheet = f"QLCDNumber {{ color: {selected_color.lower()}; }}"
        self.lcdNumber.setStyleSheet(style_sheet)

    def CheckTime(self,currentSeconds):
        # print('Checking')
        print(self.timeList)
        while self.total_seconds-currentSeconds==self.timeList[0][1]:
            print('Handler')
            self.EventHandlers(self.timeList[0])
            print('backMainThread')
            if self.timeList:
                self.timeList.popleft()

    def EventHandlers(self,eventName):
        print('EventHandlers')
        # 创建EventSignalEmitter的实例，它用于发射信号
        event_signal_emitter = EventSignalEmitter()
        # 连接信号和槽，将showSignal连接到TimerWindowShow的ResetWindow方法
        event_signal_emitter.showSignal.connect(self.start_shaking)
        # print('startNewThreadOver')
        event_thread = EventHandlerThread(eventName=eventName,ReminMissonData=self.ReminMissonData, event_listener=event_signal_emitter)
        event_thread.setDaemon(True)  # 设置为守护线程
        event_thread.start()


    def start_shaking(self):
        # 当窗口显示时触发
        self.showNormal()
        screen = QDesktopWidget().screenGeometry()
        window = self.geometry()
        x = (screen.width() - window.width()) // 2
        y = (screen.height() - window.height()) // 2
        self.move(x, y)

        self.shake_count = 0
        self.shake_timer.start(50)  # 每50毫秒触发一次

    def shake(self):
        if self.shake_count < self.shake_duration:
            dx = 5 if self.shake_count % 2 == 0 else -5
            dy = 5 if self.shake_count % 2 == 0 else -5
            current_pos = self.geometry()
            new_pos = QRect(current_pos.x() + dx, current_pos.y() + dy, current_pos.width(), current_pos.height())
            self.setGeometry(new_pos)
            self.shake_count += 1
        else:
            self.shake_timer.stop()

    def getTimeList(self, data):
        print('getTimeList',data)
        original_list = list(data.keys())
        # 使用列表推导式将元组内容转换为整数
        result_list = [(int(x), int(y)) for x, y in original_list]
        # 对元组列表按照第一个元素进行倒序排序
        sorted_list = sorted(result_list, key=lambda x: x[0])
        self.timeList = deque(sorted_list)
        self.timeList.append(('End', 'End'))
        print(self.timeList)
        # self.timeList.sort(reverse=True)

    def getdatalistsHand(self, data):
        print('getdatalistsHand', data)
        self.ReminMissonData = {}
        for i in data:
            if i[-1] != 'NULL':
                continue
            print('i',i)
            self.ReminMissonData[(i[0], i[-3])] = i
            # print(self.ReminMissonData)
        print('ReData', self.ReminMissonData)
        self.getTimeList(self.ReminMissonData)


class EventSignalEmitter(QObject):
    showSignal = pyqtSignal()

class EventHandlerThread(threading.Thread):
    def __init__(self, eventName,ReminMissonData,event_listener=None):
        super().__init__()
        # print('tttttt')
        self.eventName = tuple(map(str, eventName))
        self.ReminMissonData=ReminMissonData
        self.event_listener = event_listener

    def run(self):
        # 在这里执行事件处理的具体逻辑
        data=self.ReminMissonData[self.eventName][-2]
        if os.path.isfile(data):
            # 初始化pygame
            pygame.init()
            # 指定要播放的音频文件路径
            audio_file_path = data  # 替换为您的音频文件路径
            # 初始化音频模块
            pygame.mixer.init()
            # 加载音频文件
            pygame.mixer.music.load(audio_file_path)
            # 播放音频文件（-1表示循环播放，如果需要播放一次，可以设置为0）
            pygame.mixer.music.play(-1)
            # 等待音频播放完成（如果不加这行，程序会立即退出）
            while pygame.mixer.music.get_busy():
                pygame.time.Clock().tick(10)
            # 停止pygame
            pygame.mixer.quit()
            pygame.quit()
            print(f"This is a file path: {data}")
        else:
            print(f"This is a non-file string: {data}")
            if data[:3]=='播报:':
                # 初始化
                engine = pyttsx3.init()
                # 将要播报的文本
                text = data[3:]
                # 设置语速
                engine.setProperty('rate', 150)  # 可以调整语速, 通常默认为 200
                # 设置音量
                engine.setProperty('volume', 0.9)  # 可以调整音量, 范围在 0 到 1 之间
                # 播报文本
                engine.say(text)
                # 等待语音播报完成
                engine.runAndWait()
                print('这是一个语音播报内容：',data[3:])

            elif data=='悬浮窗弹出':
                self.event_listener.showSignal.emit()
                print('这是一个悬浮窗弹出事件',data)

if __name__ == '__main__':

    register = Register()
    while (not register.checkAuthored()):
        register.regist()

    app = QApplication([])
    mainwindow = MainWindow()
    mainwindow.show()
    sys.exit(app.exec_())


